﻿Option Explicit On

'*******************************************************************
' Program: xmlVisio
' Author: Albert E Edlund
' Date:
'
' Purpose:
' Working with visio drawing in an xml format
'
'
'
'*******************************************************************

Imports System
Imports System.Collections.Generic
Imports System.Collections.ObjectModel
Imports System.Text
Imports System.Text.StringBuilder

Imports Microsoft.Practices.EnterpriseLibrary.Common
Imports Microsoft.Practices.EnterpriseLibrary.Data
Imports Microsoft.Practices.EnterpriseLibrary.ExceptionHandling
Imports Microsoft.Practices.EnterpriseLibrary.ExceptionHandling.Logging

Imports System.IO
Imports System.Windows.Forms
Imports System.Xml
Imports System.Xml.Serialization
Imports System.Xml.Linq
Imports System.Xml.XPath

Imports <xmlns="http://schemas.microsoft.com/visio/2003/core">
Imports <xmlns:vx="http://schemas.microsoft.com/visio/2006/extension">
Imports <xmlns:v14="http://schemas.microsoft.com/office/visio/2010/extension">




Public Class frmRuleIssues



#Region " Properties and Declarations "


    '
    ' where are we keeping the drawings
    '
    Private _dataPath As String
    Public Property dataPath As String
        Get
            dataPath = _dataPath
        End Get
        Set(value As String)
            _dataPath = value
        End Set
    End Property

    '
    ' what is the latest document
    '
    Public _xDoc As XDocument
    Public Property xDoc As XDocument
        Get
            Return Me._xDoc
        End Get
        Set(value As XDocument)
            If (value Is Nothing) Then
                Throw New System.ArgumentNullException("Value", _
                    "xDoc is Null.")
            End If
            Me._xDoc = value
        End Set
    End Property


    Private _strPgNameU As String
    Public Property strPgNameU As String
        Get
            strPgNameU = _strPgNameU
        End Get
        Set(value As String)
            _strPgNameU = value
        End Set
    End Property


    '
    ' dictionary of the pages
    '
    Private _dictPage As Dictionary(Of Long, String)
    Public Property dictPage As Dictionary(Of Long, String)
        Get
            Return Me._dictPage
        End Get
        Set(value As Dictionary(Of Long, String))
            If (value Is Nothing) Then
                Throw New System.ArgumentNullException("Value", _
                    "dictPage is Null.")
            End If
            Me._dictPage = value
        End Set
    End Property

    '
    '
    '
    Public Structure stcPageShape
        Dim psPage As Long
        Dim psShape As Long
    End Structure

    '
    '
    '
    Private _dictPageShape As Dictionary(Of stcPageShape, String)
    Public Property dictPageShape As Dictionary(Of stcPageShape, String)
        Get
            Return Me._dictPageShape
        End Get
        Set(value As Dictionary(Of stcPageShape, String))
            If (value Is Nothing) Then
                Throw New System.ArgumentNullException("Value", _
                    "dictPageShape is Null.")
            End If
            Me._dictPageShape = value
        End Set
    End Property

#End Region

    '
    ' build a dictionary where the key is a structure of pageId and shapeId and the value
    ' is the ShapeNameU
    '
    Public Sub buildPageShapeDict()

        Try

            _dictPage = Nothing
            dictPage = New Dictionary(Of Long, String)
            _dictPageShape = Nothing
            _dictPageShape = New Dictionary(Of stcPageShape, String)

            Dim qryPages = xDoc...<Page>
            Dim strPageNameU As String = "NoPageNameU"
            Dim lngPageID As Long

            Dim newPageShape As stcPageShape = New stcPageShape

            For Each page In qryPages

                Dim listOfPageAttributes As IEnumerable(Of XAttribute) = _
                    From attPage In page.Attributes _
                    Select attPage

                For Each attPage As XAttribute In listOfPageAttributes
                    Select Case LCase(attPage.Name.LocalName)
                        Case "id"
                            lngPageID = CLng(attPage.Value)
                        Case "nameu"
                            strPageNameU = CStr(attPage.Value)
                    End Select
                Next attPage

                ' put the pageid into the page dictionary
                If dictPage.ContainsKey(lngPageID) = False Then
                    dictPage.Add(lngPageID, strPageNameU)
                End If

                ' get the shapes for the page
                Dim qryShapes = page...<Shape>

                For Each shape In qryShapes

                    Dim lngShapeID As Long
                    Dim strShapeNameU As String = "NoShapeNameU"

                    Dim listOfShapeAttributes As IEnumerable(Of XAttribute) = _
                        From attShape In shape.Attributes _
                        Select attShape

                    For Each attShape As XAttribute In listOfShapeAttributes
                        Select Case LCase(attShape.Name.LocalName)
                            Case "id"
                                lngShapeID = CLng(attShape.Value)
                            Case "nameu"
                                strShapeNameU = CStr(attShape.Value)
                        End Select
                    Next attShape

                    With newPageShape
                        .psPage = lngPageID
                        .psShape = lngShapeID
                    End With

                    ' put the pageid into the page dictionary
                    If dictPageShape.ContainsKey(newPageShape) = False Then
                        dictPageShape.Add(newPageShape, strShapeNameU)
                    End If

                Next shape
            Next page

        Catch errXml As XmlException
            Dim rethrow As Boolean = ExceptionPolicy.HandleException(errXml, "Log Only Policy")
            If (rethrow) Then
                Throw
            End If
        Catch err As Exception
            Dim rethrow As Boolean = ExceptionPolicy.HandleException(err, "Log Only Policy")
            If (rethrow) Then
                Throw
            End If
        End Try
    End Sub

    '
    ' load a list of Issue ids into a list control
    '
    Public Sub getRuleIssues _
        (ByRef lvControl As ListView)

        Try

            If lvControl Is Nothing Then lvControl = Me.lvIssues

            Dim qryIssues = xDoc...<v14:Issue>
            Dim intIssues As Integer = qryIssues.Count

            lvControl.Items.Clear()
            lvControl.Columns.Clear()
            lvControl.View = View.Details
            lvControl.AllowColumnReorder = True
            lvControl.FullRowSelect = True
            lvControl.Columns.Add("Id", 50, HorizontalAlignment.Right)


            Dim lvItem As ListViewItem

            For Each issue In qryIssues

                Dim lngIssueId As Long = -1

                Dim listOfAttributes As IEnumerable(Of XAttribute) = _
                    From att In issue.Attributes() _
                    Select att
                For Each att As XAttribute In listOfAttributes
                    ' Console.WriteLine("{0}={1}", att.Name.LocalName, att.Value)
                    Select Case LCase(att.Name.LocalName)
                        Case "id"
                            lngIssueId = CLng(att.Value)

                    End Select
                Next att

                lvItem = New ListViewItem(lngIssueId)


                ' add it to the listview on the data page
                lvControl.Items.Add(lvItem)

                ' do the init stuff for the first record

                If lvControl.Items.Count = 1 And _
                    lvControl.Name = "lvIssues" Then

                    getRuleInfo(issue, Me.lvRuleInfo)
                    getIssueTargetInfo(issue, Me.lvIssueTarget)

                End If
            Next issue

        Catch errXml As XmlException
            Dim rethrow As Boolean = ExceptionPolicy.HandleException(errXml, "Log Only Policy")
            If (rethrow) Then
                Throw
            End If
        Catch err As Exception
            Dim rethrow As Boolean = ExceptionPolicy.HandleException(err, "Log Only Policy")
            If (rethrow) Then
                Throw
            End If
        End Try

    End Sub

    '
    ' for a given issue get the ruleset/rule information
    '
    Private Sub getRuleInfo _
        (ByVal issueSource As XElement, _
         ByRef lvControl As ListView)


        If lvControl Is Nothing Then lvControl = Me.lvRuleInfo

        Dim qryRuleInfo = issueSource...<v14:RuleInfo>
        Dim intRuleInfo As Integer = qryRuleInfo.Count

        lvControl.Items.Clear()
        lvControl.Columns.Clear()
        lvControl.View = View.Details
        lvControl.AllowColumnReorder = True
        lvControl.FullRowSelect = True
        lvControl.Columns.Add("index", 25, HorizontalAlignment.Right)
        lvControl.Columns.Add("rulesetID", 50, HorizontalAlignment.Right)
        lvControl.Columns.Add("rulesetNameU", 100, HorizontalAlignment.Left)
        lvControl.Columns.Add("ruleID", 50, HorizontalAlignment.Right)
        lvControl.Columns.Add("ruleNameU", 200, HorizontalAlignment.Left)

        Dim intIndex As Integer = 0
        For Each ruleinfo In qryRuleInfo
            intIndex = intIndex + 1

            Dim lngRuleSetId As Long = -1
            Dim strRuleSetNameU As String = "NoRuleSetNameU"
            Dim lngRuleId As Long = -1
            Dim strRuleNameU As String = "NoRuleNameU"

            Dim lvItem As ListViewItem


            Dim listOfAttributes As IEnumerable(Of XAttribute) = _
                From att In ruleinfo.Attributes() _
                Select att
            For Each att As XAttribute In listOfAttributes

                ' Console.WriteLine("{0}={1}", att.Name.LocalName, att.Value)
                Select Case LCase(att.Name.LocalName)
                    Case "rulesetid"
                        lngRuleSetId = CLng(att.Value)
                        ' query the ruleset
                        Dim qryRules = From rulesetSel In Me.xDoc...<v14:RuleSet> _
                                Where rulesetSel.@ID = CStr(lngRuleSetId)
                                Select rulesetSel.@NameU
                        If qryRules.Count = 1 Then
                            strRuleSetNameU = qryRules.First
                        End If
                    Case "ruleid"
                        lngRuleId = CLng(att.Value)
                        ' query the ruleset
                        Dim qryRule = From ruleSel In Me.xDoc...<v14:Rule> _
                                Where ruleSel.@ID = CStr(lngRuleId)
                                Select ruleSel.@NameU
                        If qryRule.Count = 1 Then
                            strRuleNameU = qryRule.First
                        End If
                End Select
            Next att


            lvItem = New ListViewItem(intIndex)
            lvItem.SubItems.Add(lngRuleSetId)
            lvItem.SubItems.Add(strRuleSetNameU)
            lvItem.SubItems.Add(lngRuleId)
            lvItem.SubItems.Add(strRuleNameU)

            ' add it to the listview on the data page
            lvControl.Items.Add(lvItem)

        Next ruleinfo




    End Sub


    '
    ' for a given issue get the target page/shape
    '
    Private Sub getIssueTargetInfo _
        (ByVal issueSource As XElement, _
         ByRef lvControl As ListView)


        If lvControl Is Nothing Then lvControl = Me.lvIssueTarget

        Dim qryIssueTarget = issueSource...<v14:IssueTarget>
        Dim intIssueTarget As Integer = qryIssueTarget.Count

        lvControl.Items.Clear()
        lvControl.Columns.Clear()
        lvControl.View = View.Details
        lvControl.AllowColumnReorder = True
        lvControl.FullRowSelect = True
        lvControl.Columns.Add("index", 25, HorizontalAlignment.Left)
        lvControl.Columns.Add("pageID", 50, HorizontalAlignment.Right)
        lvControl.Columns.Add("pageNameU", 100, HorizontalAlignment.Left)
        lvControl.Columns.Add("shapeID", 50, HorizontalAlignment.Right)
        lvControl.Columns.Add("shapeNameU", 100, HorizontalAlignment.Left)


        Dim currPageShape As stcPageShape = New stcPageShape
        Dim intIndex As Integer = 0

        For Each target In qryIssueTarget
            intIndex = intIndex + 1

            Dim lngPageId As ULong = 0
            Dim strPageNameU As String = "NoPageNameU"
            Dim lngShapeId As ULong = 0
            Dim strShapeNameU As String = "NoShapeNameU"

            Dim lvItem As ListViewItem


            Dim listOfAttributes As IEnumerable(Of XAttribute) = _
                From att In target.Attributes() _
                Select att
            For Each att As XAttribute In listOfAttributes
                ' Console.WriteLine("{0}={1}", att.Name.LocalName, att.Value)

                Select Case LCase(att.Name.LocalName)
                    Case "pageid"
                        lngPageId = CULng(att.Value)
                    Case "shapeid"
                        lngShapeId = CULng(att.Value)
                End Select
            Next att

            With currPageShape
                .psPage = lngPageId
                .psShape = lngShapeId
            End With

            If dictPage.ContainsKey(lngPageId) = True Then
                strPageNameU = dictPage(lngPageId).ToString
            End If

            If dictPageShape.ContainsKey(currPageShape) = True Then
                strShapeNameU = dictPageShape(currPageShape).ToString
            Else
                strShapeNameU = "ShapeNotFound"
            End If

            lvItem = New ListViewItem(intIndex)
            lvItem.SubItems.Add(lngPageId)
            lvItem.SubItems.Add(strPageNameU)
            lvItem.SubItems.Add(lngShapeId)
            lvItem.SubItems.Add(strShapeNameU)

            ' add it to the listview on the data page
            lvControl.Items.Add(lvItem)

        Next target


    End Sub

    '
    '
    '
    Private Sub AboutToolStripMenuItem_Click(sender As System.Object, e As System.EventArgs) Handles AboutToolStripMenuItem.Click
        frmAbout.ShowDialog()
    End Sub

    '
    '
    '
    Private Sub ExitToolStripMenuItem_Click(sender As System.Object, e As System.EventArgs) Handles ExitToolStripMenuItem.Click
        Me.Close()
    End Sub


    '
    '
    '
    Private Sub lvIssues_SelectedIndexChanged(sender As System.Object, e As System.EventArgs) Handles lvIssues.SelectedIndexChanged

        Dim issueItems As ListView.SelectedListViewItemCollection = lvIssues.SelectedItems
        Dim issueItem As ListViewItem
        Dim lngId As Long

        If 0 < issueItems.Count Then

            issueItem = issueItems(0)

            ' query the rules
            Dim qryIssue = From issueSel In Me.xDoc...<v14:Issue> _
                    Where issueSel.@ID = issueItem.SubItems(0).Text

            If qryIssue.Count = 1 Then
                getRuleInfo(qryIssue.First, Me.lvRuleInfo)
                getIssueTargetInfo(qryIssue.First, Me.lvIssueTarget)
            Else
                MsgBox("could not find issue")
            End If ' test that only one issue was found

        End If ' test for something selected
    End Sub

End Class